# Virtual Router Simulator 
#
# Copyright (C) 2009-2010 VRSim Project
# Author: Choonho Son <choonho@kt.com>
# URL: <http://vrsim.googlecode.com>
# For license information, see LICENSE.TXT
#

# proxy_libvirt client
#
#     GUI client -> proxy_libvirt ----> proxy_libvirtd -> libvirt -> QEMU
# 
# Proxy works as UDP client
# supportted API
#   - libvirt.open(URI) -> return Domain
#   - 
import telnetlib
from socket import *
from xml.dom import minidom
from VRSim.Utils import debug
from VRSim.Node.XML import XML
import VRSim.Globals as globals

def open(uri):
    """ connect to proxy-libvirtd
    uri: qemu+proxy:///IP:[PORT]
    default Port: 8000
    """
    debug("called proxy_libvirt:open")
    conn = Proxy_Connection(uri)
    return conn
 
def parseURI(uri):
    """ parse URI
    return (ID, PW, IP, Port)
    """
    temp = uri.split(":///")
    if temp[0] != "qemu+proxy":
        debug("URI type error",  temp[0])
        return False
        
    # IP[:PORT]
    ipnport = temp[1].split(":")
    ip = ipnport[0]
    port = 8000
    if len(ipnport) > 1:
        port = int(ipnport[1])
    return (ip,  port)
     
def getSocket(ip,  port):
    conn = socket(AF_INET,  SOCK_STREAM )
    print "connecting ..." + ip,  port
    conn.connect( (ip,  port) )
    return conn
        
class Proxy_Connection(XML):
    def __init__(self,  uri,  uuid=None):
        XML.__init__(self, "proxy_libvirt")
        self.uri = uri
        self.uuid = uuid
        self.socket = None
        self.ip = None
        self.port = None
        
    def defineXML(self,  xml):
        debug(xml)
        self.name = self.getNodeName(xml)
        # create socket
        if self.socket == None:
            parse = parseURI(self.uri)
            if parse == False:
                msg = "URI format: %s is wrong!" % self.uri
                debug(msg)
                return False
            (self.ip,  self.port) = parse
            self.socket = getSocket(self.ip,  self.port)
        
        output = "<proxy_libvirt>"
        output += "<opcode name='defineXML'/>"
        output += "<content>"
        output += xml
        output += "</content>"
        output += "</proxy_libvirt>"
        
        globals.GApp.my_logger.debug(output)
        self.socket.send(output)
        
        # recv
        result = None
        while 1:
            result = self.socket.recv(1024)
            globals.GApp.my_logger.debug("return value of defineXML(%s)" % result)
            if result == "True":
                return Proxy_Domain(self.socket,  self.uri,  self.name)
            if not result: break
        
        # error
        msg = globals.errorMsg["defineXML"]
        nmsg = msg % self.name
        globals.GApp.mainWindow.NodesLog.addError(nmsg)
        return False
            
    def getUUID(self,  xml):
        root = minidom.parseString(xml)
        node_uuid = root.getElementsByTagName("uuid")[0]
        uuid = node_uuid.firstChild.data
        return uuid
      
    def getNodeName(self,  xml): 
        root = minidom.parseString(xml)
        node_name = root.getElementsByTagName("name")[0]
        name = node_name.firstChild.data
        return name
       
        
class Proxy_Domain:
    def __init__(self,  sock,  uri,  name):
        self.uri = uri
        self.socket= sock
        self.nodeName = name
        (self.ip,  self.port) = parseURI(uri)
        #tf = self.parseURI()
        #self.conn = getSocket()
        
        
        
    def create(self):
        """ proxy for domain.create()
        """
        # create socket
        msg = "proxy_libvirt:create"
        globals.GApp.my_logger.debug(msg)
        self.socket = None
        if self.socket == None:
            parse = parseURI(self.uri)
            if parse == False:
                msg = "URI format: %s is wrong!" % self.uri
                debug(msg)
                return False
            (self.ip,  self.port) = parse
            self.socket = getSocket(self.ip,  self.port)
        
        output = "<proxy_libvirt>"
        output += "<opcode name='create'/>"
        output += "<domain name='" + self.nodeName + "'/>"
        output += "</proxy_libvirt>"
        
        debug(output)
        self.socket.send(output)
        while 1:
            result = self.socket.recv(1024)
            if result == "True":
                globals.GApp.my_logger.debug("Create result %s" % result)
                return True
            if not result: break
        
        return False
    
        
    def suspend(self):
        """ proxy for domain.suspend()
        """
        # create socket
        debug("proxy_libvirt:suspend")
        parse = parseURI(self.uri)
        if parse == False:
            msg = "URI format: %s is wrong!" % self.uri
            debug(msg)
            return False
        (self.ip,  self.port) = parse
        self.socket = getSocket(self.ip,  self.port)
        
        output = "<proxy_libvirt>"
        output += "<opcode name='suspend'/>"
        output += "<domain name='" + self.nodeName + "'/>"
        output += "</proxy_libvirt>"
        
        debug(output)
        self.socket.send(output)
        while 1:
            result = self.socket.recv(1024)
            if result == "True":
                globals.GApp.my_logger.debug("suspend result %s" % result)
                return True
            if not result: break
        
        return False
        
        
    def shutdown(self):
        """ proxy for domain.shutdown()
        """
        # create socket
        debug("proxy_libvirt:stop")
        parse = parseURI(self.uri)
        if parse == False:
            msg = "URI format: %s is wrong!" % self.uri
            debug(msg)
            return False
        (self.ip,  self.port) = parse
        self.socket = getSocket(self.ip,  self.port)
        
        output = "<proxy_libvirt>"
        output += "<opcode name='stop'/>"
        output += "<domain name='" + self.nodeName + "'/>"
        output += "</proxy_libvirt>"
        
        debug(output)
        self.socket.send(output)
        
        while 1:
            result = self.socket.recv(1024)
            if result == "True":
                globals.GApp.my_logger.debug("shutdown result %s" % result)
                return True
            if not result: break
        
        return False
        
        
